package com.jy.framework.sys.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.jy.framework.base.TreeEntity;
import com.jy.framework.dto.TreeEntityDTO;
import com.jy.framework.sys.dao.TreeDao;
import com.jy.framework.sys.entity.SysAreaEntity;
import com.jy.framework.sys.entity.SysMenuEntity;
import com.jy.framework.sys.service.TreeService;
import com.jy.framework.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMapping;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Service("treeService")
@Slf4j
public class TreeServiceImpl implements TreeService {
    @Autowired
    private TreeDao treeDao;

    @Override
    public <T extends TreeEntity> void updateParentIds(IService<T> service, T entity) {
        T byId = service.getById(entity.getId());
        if (entity.getParentId().equals(byId.getParentId()) && StringUtils.isNotBlank(byId.getParentIds())) {
            return;
        }
        entity.setParentIds(null);
        Map<String, Object> params = buildParams((T) entity);
        treeDao.updateTreeNode(params);
        log.info("本次修改：" + params.get("count_") + " 个节点");
    }

    @Override
    public <T extends TreeEntity> void delByParentId(IService<T> service, Serializable id) {
        T entity = service.getById(id);
        Map<String, Object> params = buildParams((T) entity);
        treeDao.delTreeNode(params);
        log.info("本次删除：" + params.get("count_") + " 个节点");
    }

    private <T extends TreeEntity> Map<String, Object> buildParams(T entity) {
        Map<String, Object> params = new HashMap<>(4);
        TableName tableName = entity.getClass().getAnnotation(TableName.class);
        params.put("treeTable", tableName.value());
        params.put("treeId", entity.getId());
        params.put("newTreeParentId", entity.getParentId());
        params.put("treeCount", null);
        return params;
    }

    @Override
    public <T extends TreeEntity> void fillParentIds(IService<T> service) {
        List<T> list = service.list(new QueryWrapper<>());
        Map<Long, T> collect = list.stream().collect(Collectors.toMap(key -> key.getId(), val -> val));
        List<T> tree = TreeEntityDTO.createTree(0L, list);
        List<T> fullTree = new ArrayList<>();
        fillParentIds(tree, collect, fullTree);
        service.updateBatchById(fullTree);
    }

    private <T extends TreeEntity> void fillParentIds(List<? extends TreeEntity> tree, Map<Long, T> collect, List fullTree) {
        tree.stream().forEach(t1 -> {
            Long parentId = t1.getParentId();
            T pSysAreaEntity = collect.get(parentId);
            if (null != pSysAreaEntity && StringUtils.isNotBlank(pSysAreaEntity.getParentIds())) {
                t1.setParentIds(pSysAreaEntity.getParentIds() + parentId + ",");
            } else {
                t1.setParentIds("," + parentId + ",");
            }
            fullTree.add(t1);
            List<? extends TreeEntity> nodes = t1.getNodes();
            if (CollectionUtil.isNotEmpty(nodes)) {
                fillParentIds(nodes, collect, fullTree);
            }
        });
    }

    /**
     * @Author: JuiceYan
     * @Description: 填充上级节点名
     * @param: [sysMenuService]
     * @return: java.util.List<T>
     * @throws:
     * @Date: 9:11 2018/12/22
     */
    @Override
    public <T extends TreeEntity> List<T> fillParentName(IService<T> sysMenuService) {
        List<T> treeList = sysMenuService.list(null);
        Map<Long, T> treeEntityMap = treeList.stream().collect(Collectors.toMap(key -> key.getId(), value -> value));
        for (T treeEntity : treeList) {
            T parentTreeEntity = treeEntityMap.get(treeEntity.getParentId());
            if (parentTreeEntity != null) {
                treeEntity.setParentName(parentTreeEntity.getName());
            }
        }
        return treeList;
    }
}
